package br.net.atasacramental.atividade.business;
import br.net.atasacramental.atividade.dao.EventoDAO;
import br.net.atasacramental.atividade.model.AtividadePrivilegioGrupo;
import br.net.atasacramental.atividade.model.Evento;
import br.net.atasacramental.atividade.model.EventoStatus;
import br.net.atasacramental.atividade.model.EventoView;
import br.net.atasacramental.organizacao.business.OrganizacaoBLL;
import br.net.atasacramental.organizacao.business.OrganizacaoLancamentoBLL;
import br.net.atasacramental.organizacao.model.Organizacao;
import br.net.atasacramental.organizacao.model.OrganizacaoOrcamentoView;
import br.net.atasacramental.usuario.model.Usuario;
import br.net.atasacramental.util.Paginacao;
import br.net.atasacramental.util.PaginacaoPeriodo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import under.wsl.service.Service;
/**
 * @author alexandre.araujo
 */
public class EventoBLL {
    private EventoDAO dao = null;
    public EventoBLL() {
        this.dao = new EventoDAO();
    }
    @Service(cache=true)
    public List<Evento> get(){
        return this.dao.get();
    }
    @Service(cache=false)
    public List<Evento> getPaginado(Paginacao pag){
        return this.dao.getPaginado(pag);
    }
    @Service()
    public Evento getByIdEvento(int idEvento) {
        return this.dao.getByIdEvento(idEvento);
    }
    
    @Service()
    public List<Evento> getByDescricao(String descricao) {
        return this.dao.getByDescricao(descricao);
    }
    
    @Service()
    public List<Evento> getByDetalhes(String detalhes) {
        return this.dao.getByDetalhes(detalhes);
    }
    
    @Service()
    public List<Evento> getByMomento(Date momento) {
        return this.dao.getByMomento(momento);
    }
    
    @Service()
    public List<Evento> getAprovadasELiberadasByPeriodo(PaginacaoPeriodo p) {
        return this.dao.getAprovadasELiberadasByPeriodo(p.getInicio(),p.getFim());
    }
    
    @Service()
    public List<Evento> getByIdTrimestreExcludente(Evento e) {
        return this.dao.getByIdTrimestreExcludente(e);
    }
    
    @Service()
    public List<Evento> getByHora(String hora) {
        return this.dao.getByHora(hora);
    }
    
    @Service()
    public List<Evento> getByIdResponsavel(int idResponsavel) {
        return this.dao.getByIdResponsavel(idResponsavel);
    }
    
    @Service()
    public List<Evento> getByUsuarioPrivilegio(Usuario puser){
    	List<AtividadePrivilegioGrupo> apg = new AtividadePrivilegioGrupoBLL().getByIdGrupo(puser.getIdGrupo());
    	List<Evento> eventos = new ArrayList<Evento>();
    	for(int x = 0; x < apg.size(); x++){
    		List<Evento> eventostmp = this.dao.getByIdOrganizacaoEidStatusEidTrimestre(apg.get(x).getIdOrganizacao() , apg.get(x).getIdAtividadeStatus(), apg.get(x).getSnEdita(),puser.getIdTrimestre());
    		if(eventostmp.size()>0){
    			eventos.addAll(eventostmp);
    		}
    	}    	
    	return eventos;
    }
    
    @Service()
    public List<EventoView> getByUsuario(Usuario puser) {    	 
    	List<EventoView> eventos =  this.dao.getByLogin(puser.getEmail());	
        return eventos;
    }
    
    
    @Service()
    public List<EventoView> getByIdGrupo(Usuario puser) {    	 
    	List<EventoView> eventos =  this.dao.getByLogin(puser.getEmail());	
        return eventos;
    }
    @Service()
    public int getTotalByUsuario(Usuario puser) {    	 
    	return this.getByIdGrupo(puser).size();
    }
    
    @Service()
    public int getTotalAprovadasByUsuario(Usuario puser) {    	 
    	return this.dao.getByLogin(puser.getEmail(),EventoStatus.APROVADA).size();
    }
    
    @Service()
    public int getTotalEnviadasByUsuario(Usuario puser) {    
    	List<EventoView> eventos = this.dao.getByLogin(puser.getEmail(),EventoStatus.ENVIADA); 
    	return eventos.size();
    }
    
    @Service()
    public int getTotalPendentesByUsuario(Usuario puser) {    	 
    	return this.dao.getByLogin(puser.getEmail(),EventoStatus.PENDENTE).size();
    }    
    
    
    @Service()
    public List<Evento> getByOrcamento(Integer orcamento) {
        return this.dao.getByOrcamento(orcamento);
    }
    
    @Service()
    public List<Evento> getByProposito(String proposito) {
        return this.dao.getByProposito(proposito);
    }
    
    @Service()
    public List<Evento> getByIdStatus(int idStatus) {
        return this.dao.getByIdStatus(idStatus);
    }
    @Service()
    public List<Evento> getByIdTrimestre(int idTrimestre) {    	
        return this.dao.getByIdTrimestre(idTrimestre);
    }
    @Service()
    public List<Evento> getByIdOrganizacao(int idOrganizacao){
        return this.dao.getByIdOrganizacao(idOrganizacao);
    }
	@Service(cache=true)
	public List<EventoStatus> getPossiveisStatus(){
		List<EventoStatus> evestatus = new ArrayList<>();
		EventoStatus nevstatus = new EventoStatus();
		evestatus.add(new EventoStatus(EventoStatus.ELABORADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.ELABORADA)));
		evestatus.add(new EventoStatus(EventoStatus.ENVIADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.ENVIADA)));
		evestatus.add(new EventoStatus(EventoStatus.REPROVADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.REPROVADA)));
		evestatus.add(new EventoStatus(EventoStatus.APROVADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.APROVADA)));
		evestatus.add(new EventoStatus(EventoStatus.PENDENTE,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.PENDENTE)));
		evestatus.add(new EventoStatus(EventoStatus.CANCELADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.CANCELADA)));
		evestatus.add(new EventoStatus(EventoStatus.LIBERADA,nevstatus.findDescricaoByIdAtividadeStatus(EventoStatus.LIBERADA)));
		return evestatus;
	}
	
	private boolean verificaOrcamento(Evento e){
		boolean tudoOk = false;
		OrganizacaoLancamentoBLL orgbll = new OrganizacaoLancamentoBLL();	
		List<OrganizacaoOrcamentoView> oov = orgbll.getOrcamentoByOrganizacaoTrimestre(e.getIdOrganizacao(), e.getIdTrimestre());
		if(oov.size()>0){    				
			if(oov.get(0).getSaldo() >= e.getOrcamento() ){
    			tudoOk = true;
			}
		}		
		return tudoOk;
	}
	private int verificaDisponibilidade(Evento e){
		List<Evento> evts = this.getByIdTrimestreExcludente(e);
		if(evts.size() > 0){
			return evts.get(0).getIdOrganizacao();
		}
		return 0;
	}
	
    @Service(remove={"EventoBLL.get","TrimestreBLL.getDisponiveis"})
    public Evento submeter(Evento e){ 
    	boolean rt = true;
    	OrganizacaoBLL orgbll = new OrganizacaoBLL();
    	if(e.getIdStatus()==EventoStatus.ELABORADA||e.getIdStatus()==EventoStatus.ENVIADA||e.getIdStatus()==EventoStatus.APROVADA||e.getIdStatus()==EventoStatus.PENDENTE){
    		int idOutrOrg = this.verificaDisponibilidade(e);
    		if(idOutrOrg > 0){
    			e.setIdStatus(EventoStatus.PENDENTE);
    			Organizacao o = orgbll.getByIdOrganizacao(idOutrOrg);
    			e.setDsObservacao("Erro, Ja existe uma atividade da "+o.getDescricao()+" para essa data!");
    			rt=false;
    		}else if(!this.verificaOrcamento(e)){
    			e.setIdStatus(EventoStatus.PENDENTE);   
    			e.setDsObservacao("Erro, nao existe orcamento suficiente disponivel!");
    			rt=false;
    		}    		
    	}    	
    	if(rt && (e.getIdStatus()==EventoStatus.ELABORADA||e.getIdStatus()==EventoStatus.PENDENTE)){
    		e.setIdStatus(EventoStatus.ENVIADA);
    		e.setDsObservacao("Atividade enviada com sucesso, aguarde a aprovacao da atividade.");
    		e.setSnEditavel("N");
    	}else if(rt && e.getIdStatus()==EventoStatus.ENVIADA){
    		e.setIdStatus(EventoStatus.APROVADA);
    		e.setDsObservacao("Atividade aprovada com sucesso, aguarde a liberacao da atividade.");
    		e.setSnEditavel("N");
    	}else if(rt && e.getIdStatus()==EventoStatus.APROVADA){
    		e.setIdStatus(EventoStatus.LIBERADA);
    		e.setDsObservacao("Atividade liberada com sucesso!");
    		e.setSnEditavel("N");
    	}else if(e.getIdStatus() == 0){
    		e.setIdStatus(EventoStatus.ELABORADA);
    	}    	
    	this.dao.update(e);	
    	return e;
    } 
    @Service(remove={"EventoBLL.get","TrimestreBLL.getDisponiveis"})   
    public int insert(Evento e){   
    	e.setIdStatus(EventoStatus.ELABORADA);
        if(this.dao.insert(e)){            
            return e.getIdEvento();
        }
        return 0;
    }
    @Service(remove={"EventoBLL.get","TrimestreBLL.getDisponiveis"})
    public boolean update(Evento e){
    	if(e.getSnEditavel().equals("S")){
   		 	return this.dao.update(e);
    	}    	
    	return false;
    }
    @Service(remove={"EventoBLL.get","TrimestreBLL.getDisponiveis"})
    public boolean delete(Evento e){
    	if(e.getSnEditavel().equals("S")){
    		 e.setIdStatus(EventoStatus.CANCELADA);
    		 return this.dao.update(e);
    	}    	
    	return false;
    }  
}
